package playlist

import (
	"encoding/json"
	"fmt"
	"math/rand"
	"os"
	"path/filepath"
	"sync"
	"time"

	"gitee.com/rw555/fdsmastergo/pkg/audioplayer"
)

// 初始化随机数种子
func init() {
	rand.Seed(time.Now().UnixNano())
}

// PlaylistManager 播放列表管理器接口
type PlaylistManager interface {
	// 播放列表基本操作
	CreatePlaylist(name string) (*Playlist, error)
	GetPlaylist(id string) (*Playlist, error)
	GetDefaultPlaylist() (*Playlist, error)
	UpdatePlaylist(playlist *Playlist) error
	DeletePlaylist(id string) error
	ListPlaylists() ([]*Playlist, error)
	SetDefaultPlaylist(id string) error

	// 播放列表项操作
	AddItem(playlistID string, item PlaylistItem) error
	RemoveItem(playlistID string, itemID string) error
	ClearPlaylist(playlistID string) error
	MoveItem(playlistID string, fromIndex, toIndex int) error

	// 持久化操作
	SavePlaylists() error
	LoadPlaylists() error

	// 同步到播放器
	SyncToPlayer(playlistID string) error
}

// DefaultPlaylistManager 默认的播放列表管理器实现
type DefaultPlaylistManager struct {
	sync.RWMutex
	playlists     map[string]*Playlist    // ID到播放列表的映射
	defaultID     string                  // 默认播放列表ID
	storagePath   string                  // 存储路径
	currentPlayer audioplayer.AudioPlayer // 当前播放器引用
	indexFile     string                  // 索引文件路径
	playlistDir   string                  // 播放列表目录
}

// NewPlaylistManager 创建新的播放列表管理器
func NewPlaylistManager(storagePath string, player audioplayer.AudioPlayer) (PlaylistManager, error) {
	// 确保存储目录存在
	if err := os.MkdirAll(storagePath, 0755); err != nil {
		return nil, fmt.Errorf("创建播放列表存储目录失败: %w", err)
	}

	// 创建并初始化播放列表管理器
	pm := &DefaultPlaylistManager{
		playlists:     make(map[string]*Playlist),
		defaultID:     "",
		storagePath:   storagePath,
		currentPlayer: player,
		indexFile:     filepath.Join(storagePath, "index.json"),
		playlistDir:   storagePath,
	}

	return pm, nil
}

// 以下是DefaultPlaylistManager的方法实现

// CreatePlaylist 创建新的播放列表
func (pm *DefaultPlaylistManager) CreatePlaylist(name string) (*Playlist, error) {
	pm.Lock()
	defer pm.Unlock()

	// 生成唯一ID
	id := generateUniqueID()

	// 创建播放列表
	now := time.Now()
	playlist := &Playlist{
		ID:        id,
		Name:      name,
		Items:     []PlaylistItem{},
		CreatedAt: now,
		UpdatedAt: now,
	}

	// 添加到映射
	pm.playlists[id] = playlist

	// 如果是第一个播放列表，设为默认
	if pm.defaultID == "" {
		pm.defaultID = id
	}

	// 保存到文件
	if err := pm.savePlaylistToFile(playlist); err != nil {
		return nil, fmt.Errorf("保存播放列表失败: %w", err)
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return nil, fmt.Errorf("更新索引失败: %w", err)
	}

	return playlist, nil
}

// GetPlaylist 获取指定ID的播放列表
func (pm *DefaultPlaylistManager) GetPlaylist(id string) (*Playlist, error) {
	pm.RLock()
	defer pm.RUnlock()

	playlist, exists := pm.playlists[id]
	if !exists {
		return nil, fmt.Errorf("播放列表不存在")
	}

	return playlist, nil
}

// GetDefaultPlaylist 获取默认播放列表
func (pm *DefaultPlaylistManager) GetDefaultPlaylist() (*Playlist, error) {
	pm.RLock()
	defer pm.RUnlock()

	if pm.defaultID == "" {
		return nil, fmt.Errorf("没有设置默认播放列表")
	}

	playlist, exists := pm.playlists[pm.defaultID]
	if !exists {
		return nil, fmt.Errorf("默认播放列表不存在")
	}

	return playlist, nil
}

// UpdatePlaylist 更新播放列表
func (pm *DefaultPlaylistManager) UpdatePlaylist(playlist *Playlist) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查播放列表是否存在
	_, exists := pm.playlists[playlist.ID]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 更新时间戳
	playlist.UpdatedAt = time.Now()

	// 更新播放列表
	pm.playlists[playlist.ID] = playlist

	// 保存到文件
	if err := pm.savePlaylistToFile(playlist); err != nil {
		return fmt.Errorf("保存播放列表失败: %w", err)
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// DeletePlaylist 删除播放列表
func (pm *DefaultPlaylistManager) DeletePlaylist(id string) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查是否为默认播放列表
	if id == pm.defaultID {
		return fmt.Errorf("不能删除默认播放列表")
	}

	// 检查播放列表是否存在
	_, exists := pm.playlists[id]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 删除播放列表文件
	playlistFile := filepath.Join(pm.playlistDir, id+".json")
	if err := os.Remove(playlistFile); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("删除播放列表文件失败: %w", err)
	}

	// 从映射中删除
	delete(pm.playlists, id)

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// ListPlaylists 列出所有播放列表
func (pm *DefaultPlaylistManager) ListPlaylists() ([]*Playlist, error) {
	pm.RLock()
	defer pm.RUnlock()

	// 创建结果切片
	playlists := make([]*Playlist, 0, len(pm.playlists))
	for _, playlist := range pm.playlists {
		playlists = append(playlists, playlist)
	}

	return playlists, nil
}

// SetDefaultPlaylist 设置默认播放列表
func (pm *DefaultPlaylistManager) SetDefaultPlaylist(id string) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查播放列表是否存在
	_, exists := pm.playlists[id]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 设置默认ID
	pm.defaultID = id

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// AddItem 向播放列表添加项目
func (pm *DefaultPlaylistManager) AddItem(playlistID string, item PlaylistItem) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查播放列表是否存在
	playlist, exists := pm.playlists[playlistID]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 如果没有指定ID，生成新ID
	if item.ID == "" {
		item.ID = generateUniqueID()
	}

	// 设置添加时间
	if item.AddedAt.IsZero() {
		item.AddedAt = time.Now()
	}

	// 添加项目
	playlist.Items = append(playlist.Items, item)
	playlist.UpdatedAt = time.Now()

	// 保存到文件
	if err := pm.savePlaylistToFile(playlist); err != nil {
		return fmt.Errorf("保存播放列表失败: %w", err)
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// RemoveItem 从播放列表移除项目
func (pm *DefaultPlaylistManager) RemoveItem(playlistID string, itemID string) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查播放列表是否存在
	playlist, exists := pm.playlists[playlistID]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 查找并移除项目
	found := false
	newItems := make([]PlaylistItem, 0, len(playlist.Items))
	for _, item := range playlist.Items {
		if item.ID != itemID {
			newItems = append(newItems, item)
		} else {
			found = true
		}
	}

	if !found {
		return fmt.Errorf("项目不存在")
	}

	// 更新播放列表
	playlist.Items = newItems
	playlist.UpdatedAt = time.Now()

	// 保存到文件
	if err := pm.savePlaylistToFile(playlist); err != nil {
		return fmt.Errorf("保存播放列表失败: %w", err)
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// ClearPlaylist 清空播放列表
func (pm *DefaultPlaylistManager) ClearPlaylist(playlistID string) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查播放列表是否存在
	playlist, exists := pm.playlists[playlistID]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 清空项目
	playlist.Items = []PlaylistItem{}
	playlist.UpdatedAt = time.Now()

	// 保存到文件
	if err := pm.savePlaylistToFile(playlist); err != nil {
		return fmt.Errorf("保存播放列表失败: %w", err)
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// MoveItem 移动播放列表中的项目
func (pm *DefaultPlaylistManager) MoveItem(playlistID string, fromIndex, toIndex int) error {
	pm.Lock()
	defer pm.Unlock()

	// 检查播放列表是否存在
	playlist, exists := pm.playlists[playlistID]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 检查索引是否有效
	if fromIndex < 0 || fromIndex >= len(playlist.Items) || toIndex < 0 || toIndex >= len(playlist.Items) {
		return fmt.Errorf("索引无效")
	}

	// 移动项目
	item := playlist.Items[fromIndex]
	playlist.Items = append(playlist.Items[:fromIndex], playlist.Items[fromIndex+1:]...)
	newItems := make([]PlaylistItem, 0, len(playlist.Items)+1)
	newItems = append(newItems, playlist.Items[:toIndex]...)
	newItems = append(newItems, item)
	newItems = append(newItems, playlist.Items[toIndex:]...)
	playlist.Items = newItems
	playlist.UpdatedAt = time.Now()

	// 保存到文件
	if err := pm.savePlaylistToFile(playlist); err != nil {
		return fmt.Errorf("保存播放列表失败: %w", err)
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// SavePlaylists 保存所有播放列表
func (pm *DefaultPlaylistManager) SavePlaylists() error {
	pm.RLock()
	defer pm.RUnlock()

	// 为每个播放列表保存文件
	for _, playlist := range pm.playlists {
		if err := pm.savePlaylistToFile(playlist); err != nil {
			return fmt.Errorf("保存播放列表 '%s' 失败: %w", playlist.Name, err)
		}
	}

	// 更新索引
	if err := pm.updateIndex(); err != nil {
		return fmt.Errorf("更新索引失败: %w", err)
	}

	return nil
}

// LoadPlaylists 加载所有播放列表
func (pm *DefaultPlaylistManager) LoadPlaylists() error {
	pm.Lock()
	defer pm.Unlock()

	// 清空当前播放列表
	pm.playlists = make(map[string]*Playlist)

	// 尝试加载索引
	index, err := pm.loadIndex()
	if err != nil {
		// 如果索引不存在，创建默认播放列表
		if os.IsNotExist(err) {
			// 创建默认播放列表
			defaultPlaylist := &Playlist{
				ID:        "default",
				Name:      "默认播放列表",
				Items:     []PlaylistItem{},
				CreatedAt: time.Now(),
				UpdatedAt: time.Now(),
			}
			pm.playlists["default"] = defaultPlaylist
			pm.defaultID = "default"

			// 保存默认播放列表
			if err := pm.savePlaylistToFile(defaultPlaylist); err != nil {
				return fmt.Errorf("保存默认播放列表失败: %w", err)
			}

			// 更新索引
			if err := pm.updateIndex(); err != nil {
				return fmt.Errorf("更新索引失败: %w", err)
			}

			return nil
		}
		return fmt.Errorf("加载播放列表索引失败: %w", err)
	}

	// 设置默认播放列表ID
	pm.defaultID = index.DefaultPlaylistID

	// 加载所有播放列表
	for _, meta := range index.Playlists {
		playlist, err := pm.loadPlaylistFromFile(meta.ID)
		if err != nil {
			return fmt.Errorf("加载播放列表 '%s' 失败: %w", meta.Name, err)
		}
		pm.playlists[meta.ID] = playlist
	}

	// 如果没有默认播放列表，创建一个
	if pm.defaultID == "" && len(pm.playlists) > 0 {
		// 随便选一个作为默认
		for id := range pm.playlists {
			pm.defaultID = id
			break
		}
		// 更新索引
		if err := pm.updateIndex(); err != nil {
			return fmt.Errorf("更新索引失败: %w", err)
		}
	} else if len(pm.playlists) == 0 {
		// 创建默认播放列表
		defaultPlaylist := &Playlist{
			ID:        "default",
			Name:      "默认播放列表",
			Items:     []PlaylistItem{},
			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
		}
		pm.playlists["default"] = defaultPlaylist
		pm.defaultID = "default"

		// 保存默认播放列表
		if err := pm.savePlaylistToFile(defaultPlaylist); err != nil {
			return fmt.Errorf("保存默认播放列表失败: %w", err)
		}

		// 更新索引
		if err := pm.updateIndex(); err != nil {
			return fmt.Errorf("更新索引失败: %w", err)
		}
	}

	return nil
}

// SyncToPlayer 将播放列表同步到播放器
func (pm *DefaultPlaylistManager) SyncToPlayer(playlistID string) error {
	pm.RLock()
	defer pm.RUnlock()

	// 检查播放列表是否存在
	playlist, exists := pm.playlists[playlistID]
	if !exists {
		return fmt.Errorf("播放列表不存在")
	}

	// 检查播放器是否可用
	if pm.currentPlayer == nil {
		return fmt.Errorf("播放器未初始化")
	}

	// 清空当前播放列表
	if err := pm.currentPlayer.ClearPlaylist(); err != nil {
		return fmt.Errorf("清空播放器播放列表失败: %w", err)
	}

	// 将项目添加到播放器
	for _, item := range playlist.Items {
		audioSource := audioplayer.AudioSource{
			Path:   item.Path,
			Format: audioplayer.AudioFormat(item.Format),
			Name:   item.Name,
		}
		if err := pm.currentPlayer.AddToPlaylist(audioSource); err != nil {
			return fmt.Errorf("添加项目到播放器失败: %w", err)
		}
	}

	return nil
}

// 辅助方法：更新索引文件
func (pm *DefaultPlaylistManager) updateIndex() error {
	// 创建索引对象
	index := PlaylistIndex{
		Version:           "1.0",
		LastUpdated:       time.Now(),
		DefaultPlaylistID: pm.defaultID,
		Playlists:         make([]PlaylistMeta, 0, len(pm.playlists)),
	}

	// 添加所有播放列表的元数据
	for _, playlist := range pm.playlists {
		meta := PlaylistMeta{
			ID:        playlist.ID,
			Name:      playlist.Name,
			ItemCount: len(playlist.Items),
			CreatedAt: playlist.CreatedAt,
			UpdatedAt: playlist.UpdatedAt,
		}
		index.Playlists = append(index.Playlists, meta)
	}

	// 将索引序列化为JSON
	data, err := json.MarshalIndent(index, "", "  ")
	if err != nil {
		return fmt.Errorf("序列化索引失败: %w", err)
	}

	// 写入文件
	if err := os.WriteFile(pm.indexFile, data, 0644); err != nil {
		return fmt.Errorf("写入索引文件失败: %w", err)
	}

	return nil
}

// 辅助方法：加载索引文件
func (pm *DefaultPlaylistManager) loadIndex() (PlaylistIndex, error) {
	// 检查索引文件是否存在
	if _, err := os.Stat(pm.indexFile); os.IsNotExist(err) {
		return PlaylistIndex{}, err
	}

	// 读取索引文件
	data, err := os.ReadFile(pm.indexFile)
	if err != nil {
		return PlaylistIndex{}, fmt.Errorf("读取索引文件失败: %w", err)
	}

	// 解析JSON
	var index PlaylistIndex
	if err := json.Unmarshal(data, &index); err != nil {
		return PlaylistIndex{}, fmt.Errorf("解析索引文件失败: %w", err)
	}

	return index, nil
}

// 辅助方法：将播放列表保存到文件
func (pm *DefaultPlaylistManager) savePlaylistToFile(playlist *Playlist) error {
	// 构建文件路径
	filePath := filepath.Join(pm.playlistDir, playlist.ID+".json")

	// 序列化为JSON
	data, err := json.MarshalIndent(playlist, "", "  ")
	if err != nil {
		return fmt.Errorf("序列化播放列表失败: %w", err)
	}

	// 写入文件
	if err := os.WriteFile(filePath, data, 0644); err != nil {
		return fmt.Errorf("写入播放列表文件失败: %w", err)
	}

	return nil
}

// 辅助方法：从文件加载播放列表
func (pm *DefaultPlaylistManager) loadPlaylistFromFile(id string) (*Playlist, error) {
	// 构建文件路径
	filePath := filepath.Join(pm.playlistDir, id+".json")

	// 检查文件是否存在
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		return nil, fmt.Errorf("播放列表文件不存在")
	}

	// 读取文件
	data, err := os.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("读取播放列表文件失败: %w", err)
	}

	// 解析JSON
	var playlist Playlist
	if err := json.Unmarshal(data, &playlist); err != nil {
		return nil, fmt.Errorf("解析播放列表文件失败: %w", err)
	}

	return &playlist, nil
}

// 辅助函数：生成唯一ID
func generateUniqueID() string {
	// 使用时间戳和随机数生成唯一ID
	timestamp := time.Now().UnixNano()
	randomPart := rand.Intn(10000) // 假设已经导入了math/rand包
	return fmt.Sprintf("%d-%d", timestamp, randomPart)
}
